<?php

namespace App\Http\Controllers;

use App\Contract\OrderStatus;
use App\Contract\OrderType;
use App\Http\Service\AdaPayService;
use App\Http\Service\DeviceService;
use App\Model\AgentAmountLog;
use App\Model\Bill;
use App\Model\BillPay;
use App\Model\Business;
use App\Model\BusinessConf;
use App\Model\DeviceTask;
use App\Model\Message;
use App\Model\Order;
use App\Model\UserAmountLog;
use App\Model\UserBank;
use App\Model\UserCashLog;
use App\Model\UserRefund;
use App\Service\Baofu;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class PaymentNotifyController
{
    public function notify(Request $request)
    {
        $baofu = App::make(Baofu::class); // 通过容器解析依赖
        Log::info('payment notify', $request->all());
        $data = $request->input('dataContent');
        $sign = $request->input('signStr');
        $type = $request->input('notifyType');
        $code = $request->input('returnCode');

        if(!$baofu->signNotify($data,$sign)){
            Log::error('支付回调验签失败', [$request->all()]);
            return 'fail';
        }
//        $payment = AdaPayService::getPayment();
//        if (!$payment->ada_tools->verifySign($sign, $data)) {
//            Log::error('支付回调验签失败', [$request->all()]);
//            return 'fail';
//        }
        switch ($type) {
            case 'PAYMENT':
                if($code == 'SUCCESS'){
                    $data = json_decode($data,true);
                    $this->paySuccess($data);
                }
                // 支付成功
                break;
            case 'REFUND':
                    $data = json_decode($data,true);
                    $this->refundNotify($data);
                break;
            case 'refund.succeeded':
                $data = json_decode($data);
                $this->refundStatus($data);
                // 退款成功
                break;
            case 'refund.failed':
                $data = json_decode($data);
                $this->refundStatus($data);
                // 退款失败

            case 'fast_card.succeeded':
                // 快捷绑卡确认成功
                break;
            case 'fast_card.failed':
                // 快捷绑卡确认失败
                break;
            case 'cash.failed':
                // 取现失败
                $this->drawCashStatus(json_decode($data), 'F');
                break;
            case 'cash.succeeded':
                // 取现成功
                $this->drawCashStatus(json_decode($data), 'S');
                break;
            case 'corp_member.succeeded':
                $this->notifyMember(json_decode($data,true),2);
                break;
            case 'corp_member.failed':
                $this->notifyMember(json_decode($data,true),3);
                break;
            case 'corp_member_update.succeeded':
                $this->notifyMember(json_decode($data,true),2);
                break;
            case 'corp_member_update.failed':
                $this->notifyMember(json_decode($data,true),3);
                break;
        }
        return 'OK';
    }

    /**开户回调
     * @param $data
     * @param $status
     * @return void
     */
    public function notifyMember($data,$status){
        $bank = UserBank::query()->where('order_no',$data['order_no'])->first();
        if(!$bank){
            return '';
        }
        $userInfo = User::query()->where('id',$bank->user_id)->first();
        $bank->notify_time = date('Y-m-d H:i:s',time());
        $bank->result = json_encode($data);
        $bank->save();
        if($data['audit_state'] == 'D' || $data['audit_state'] == 'E'){
            if(array_key_exists('settle_account_id',$data)){
                $userInfo->account_id  = $bank->account_id = $data['settle_account_id'];
            }
            if(array_key_exists('audit_desc',$data)){
                $bank->reason = $data['audit_desc'];
            }else{
                $bank->reason = '开户成功';
            }
            $userInfo->member_id = $data['member_id'];
            $bank->status = $status;
            $userInfo->member_id = $data['member_id'];
            $userInfo->save();
        }else{
            $bank->status = $status;
            if(array_key_exists('audit_desc',$data)){
                $bank->reason = $data['audit_desc'];
            }else{
                $bank->reason = '开户失败';
            }
        }
        $bank->save();
    }


    public function paySuccess($data)
    {

        $order = Order::query()->where('order_no',$data['outTradeNo'] )->with(['user', 'business', 'business.user'])->first();
        if(!$order){
            Log::info('订单不存在',[$data]);
            return;
        }
        if($data['txnState'] != 'SUCCESS'){
            Log::info('订单支付失败',[$data]);
            return ;
        }
        if(isset($data['chlRetParam']['transaction_id'])){
            $order->out_trade_id = $data['chlRetParam']['transaction_id'];
        }
        if(isset($data['chlRetParam']['trade_no'])){
            $order->out_trade_id = $data['chlRetParam']['trade_no'];
        }
        if ($order->status == OrderStatus::SUCCEEDED) {
            Log::info('订单已支付过了', [$order]);
            return;
        }
        $order->status = OrderStatus::SUCCEEDED;
        $order->paid_at = now()->toDateTimeString();
        if(isset($data['chlRetParam']['transaction_id'])){
            $order->out_trade_id = $data['chlRetParam']['transaction_id'];
        }
        $order->payment_id = $data['tradeNo'];
        $order->save();

        $amount = $order->pay_amt - $order->fee;
        $fd = $order->business->user;
        if ($order->type != OrderType::ELECTRIC && $order->type != OrderType::TEMP ) {
            // 写入房东余额
            $fd->amount += $amount;
            $fd->total_amount += $amount;
            $fd->save();

            // 写入账户明细
            UserAmountLog::create([
                'user_id' => $fd->id,
                'type' => $order->type,
                'amount' => $amount,
                'order_id' => $order->id,
                'log' => '线上支付收入'
            ]);
            // 写入房东消息
            Message::create([
                'user_id'=> $fd->id,
                'title' => '账单支付成功通知',
                'content' => '支付项目：' . $order->goods_desc . ' <br> 到账金额：￥' . $amount
            ]);
        }

        if ($order->type == OrderType::ELECTRIC) {

        }

        // 房租或押金,更改账单支付状态
        if ($order->type == OrderType::RENT OR $order->type == OrderType::DEPOSIT) {
            $billList = Bill::query()->whereIn('id', $order->bill_id)->get();
            foreach ($billList as $bill) {
                $businessConf = BusinessConf::query()->where('business_id', $bill->business_id)->first();
                if ($businessConf && $businessConf->fee_payer == 2) {
                    $bill->fee_payer = 2;
                }else{
                    $bill->fee_payer = 1;
                }
                $bill->is_paid = 1;
                $bill->paid_at = $order->paid_at;
                $bill->save();
                $billPay = new BillPay();
                $billPay->fill([
                    'sn' => $order->order_no,
                    'bill_id' => $bill->id,
                    'amount' => $amount,
                    'payment' => $order->pay_channel == 'wx_lite' ? 4 : 5,
                    'is_paid' => 1,
                    'paid_at' => $order->paid_at,
                ]);
                $billPay->save();
                // 增加合闸任务
                DeviceTask::create([
                    'contract_id' => $bill->contract_id,
                ]);
            }
        }

    }

    /**退款
     * @param $data
     * @return string|void
     */
    public function refundNotify($data){
        $refund  = UserRefund::query()->where('refund_no',$data['outTradeNo'])->first();
        if(!$refund){
            return '';
        }
        if($data['refundState'] == 'SUCCESS'){
            $order = Order::query()->where('order_no',$refund->order_no)->first();
            $order->return_fee = $data['succAmt']?round($data['succAmt']/100,2):0;
            $order->status = 4;
            $order->recharge_status = 4;
//            if(!($order->type == 3 && $order->recharge_status != 3)){
//                $business = Business::query()->where('id',$order->business_id)->first();
//                $user = User::query()->where('id',$business->user_id)->first();
//                $user->amount-= number_format($order->pay_amt-$order->fee,2);
//                $user->save();
//            }
            $order->save();
            $refund->status = 1;
            if($refund->type == 1){
                $bus = Business::query()->where('id',$order->business_id)->first();
                if($bus){
                    $user = User::query()->where('id',$bus->user_id)->first();
                    if($user){
                        $user->total_amount-= number_format($order->pay_amt-$order->fee,2);
                        $user->amount-= number_format($order->pay_amt-$order->fee,2);
                        $user->save();
                        $bill = new Bill();
                        $bill->fill([
                            'business_id' => $order->business_id,
                            'mobile' => $order->user->mobile,
                            'house_id' => $order->house_id,
                            'device_id' => $order->device_id,
                            'title' => '充值退款'.-number_format($order->pay_amt-$order->fee,2),
                            'amount' => -number_format($order->pay_amt-$order->fee,2),
                            'type' => OrderType::ELECTRIC,
                            'is_paid' => 1,
                            'target_id' =>$order->id,
                            'paid_at' => date('Y-m-d H:i:s',time()),
                            //'pay_date' => now()->toDateString(),
                        ]);
                        $bill->save();
                    }
                }
            }
        }else{
            $refund->status = 2;
        }
        $refund->error_msg = json_encode($data,true);
        $refund->save();
    }

    public function drawCashStatus($data, $status)
    {
        $cashLog = UserCashLog::query()->where('order_no', $data->order_no)->with(['user'])->first();
        $cashLog->status = $status;
        $cashLog->save();
        if ($status == 'F') {
            if($cashLog->pay_no){
                $cashLog->refund_no =  "BCRF_". date("YmdHis").rand(10000, 99999);
                $params = array(
                    'app_id'=>  AdaPayService::getAppId(),
                    'balance_refund_no'=>$cashLog->refund_no,
                    'balance_refund_amt'=>$cashLog->amount,
                    'balance_seq_id'=> $cashLog->pay_no,
                    'reason' => '提现失败余额退款'.$cashLog->pay_no
                );
                $settleAccount = AdaPayService::getSettleAccount();
                $settleAccount->balanceRefund($params);
                if($settleAccount->isError()){
                    $cashLog->status = 'T';
                }else{
                    $cashLog->status = $status;
                }
            }else{
                $cashLog->status = $status;
            }
            // 扣余额
            $cashLog->user->amount += $cashLog->cash_amt;
            $cashLog->user->save();
            // 写入账户明细
            UserAmountLog::create([
                'user_id' => $cashLog->user->id,
                'type' => 6,
                'amount' => $cashLog->cash_amt,
                'log' => '提现失败退回'
            ]);

            // 写入房东消息
            Message::create([
                'user_id'=> $cashLog->user_id,
                'title' => '提现失败通知',
                'content' => '提现金额：￥' . $cashLog->cash_amt
            ]);
        } else {
            // 写入房东消息
            Message::create([
                'user_id'=> $cashLog->user_id,
                'title' => '提现成功通知',
                'content' => '提现金额：￥' . $cashLog->cash_amt
            ]);
        }
    }
}
